package com.github.xtranslation.core.threadpool;


import io.vavr.control.Option;

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 自定义线程工厂,用于创建具有特定命名规则的线程。
 * <p>
 * 支持三级命名：模块 + 类型 + 业务,便于调试和监控。
 * <p>
 * 建议使用静态工厂方法创建实例:
 * <pre>
 * MyThreadFactory factory = MyThreadFactory.create("module", "business");
 * MyThreadFactory factory = MyThreadFactory.create("module", "business", "io");
 * </pre>
 *
 * @author zhangxiaoxiang
 * @since 2025/9/5
 */
public class MyThreadFactory implements ThreadFactory {

    private static final AtomicInteger POOL_NUMBER = new AtomicInteger(1);
    private final ThreadGroup group;
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    private final String namePrefix;

    /**
     * 自定义的默认构造方法[简单套用ThreadPoolExecutor提供的默认工厂]
     */
    public MyThreadFactory() {
        SecurityManager s = System.getSecurityManager();
        group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
        namePrefix = "default-pool-" + POOL_NUMBER.getAndIncrement() + "-thread-";
    }

    /**
     * 创建一个简单的线程工厂实例
     *
     * @param prefix       模块前缀
     * @param businessType 业务类型
     * @return 线程工厂实例
     */
    public static MyThreadFactory create(String prefix, String businessType) {
        return new MyThreadFactory(prefix, businessType);
    }

    /**
     * 创建一个详细的线程工厂实例
     *
     * @param prefix       模块前缀
     * @param businessType 业务类型
     * @param threadType   线程类型（如 io/cpu）
     * @return 线程工厂实例
     */
    public static MyThreadFactory create(String prefix, String businessType, String threadType) {
        return new MyThreadFactory(prefix, businessType, threadType);
    }

    public MyThreadFactory(String prefix, String businessType) {
        this(prefix, businessType, null);
    }

    public MyThreadFactory(String prefix, String businessType, String threadType) {
        Option.of(prefix).getOrElseThrow(() -> new IllegalArgumentException("prefix cannot be null"));
        Option.of(businessType).getOrElseThrow(() -> new IllegalArgumentException("businessType cannot be null"));

        SecurityManager s = System.getSecurityManager();
        group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();

        namePrefix = Option.of(threadType)
                .map(type -> prefix + "-" + type + "-" + POOL_NUMBER.getAndIncrement() + "-" + businessType + "-")
                .getOrElse(() -> prefix + "-" + POOL_NUMBER.getAndIncrement() + "-" + businessType + "-");
    }

    /**
     * ThreadFactory 构造一个新的Thread 。 实现也可以初始化优先级,名称,守护程序状态, ThreadGroup等
     *
     * @param r Runnable
     * @return Thread
     */
    @Override
    public Thread newThread(Runnable r) {
        Option.of(r).getOrElseThrow(() -> new IllegalArgumentException("Runnable cannot be null"));

        Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);

        // 直接设置为非守护线程
        t.setDaemon(false);

        // 使用Vavr的Option处理优先级
        Option.of(t.getPriority())
                .filter(priority -> priority != Thread.NORM_PRIORITY)
                .map(priority -> {
                    t.setPriority(Thread.NORM_PRIORITY);
                    return t;
                })
                .getOrElse(t);

        return t;
    }

    @Override
    public String toString() {
        // 方便调试查看线程工厂信息
        return "MyThreadFactory{" + "namePrefix='" + namePrefix + '\'' + '}';
    }


}

